using SeataNet.Core.AT;
using SeataNet.Core.Saga;
using SeataNet.Core.TCC;
using SeataNet.Core.XA;
using System.Threading;

namespace SeataNet.Core.Context
{
    /// <summary>
    /// 事务上下文管理器
    /// </summary>
    public static class RootContext
    {
        private static readonly AsyncLocal<string?> XidContext = new();
        private static readonly AsyncLocal<string?> BranchTypeContext = new();
        private static readonly AsyncLocal<AtTransactionContext?> AtTransactionContext = new();
        private static readonly AsyncLocal<TccTransactionContext?> TccTransactionContext = new();
        private static readonly AsyncLocal<SagaTransactionContext?> SagaTransactionContext = new();
        private static readonly AsyncLocal<XaTransactionContext?> XaTransactionContext = new();
        
        /// <summary>
        /// 获取或设置全局事务ID
        /// </summary>
        public static string? Xid
        {
            get => XidContext.Value;
            set => XidContext.Value = value;
        }

        /// <summary>
        /// 获取全局事务ID
        /// </summary>
        /// <returns>全局事务ID</returns>
        public static string? GetXid()
        {
            return Xid;
        }

        /// <summary>
        /// 获取或设置分支事务类型
        /// </summary>
        public static string? BranchType
        {
            get => BranchTypeContext.Value;
            set => BranchTypeContext.Value = value;
        }
        
        /// <summary>
        /// 获取或设置AT事务上下文
        /// </summary>
        public static AtTransactionContext? AtContext
        {
            get => AtTransactionContext.Value;
            set => AtTransactionContext.Value = value;
        }
        
        /// <summary>
        /// 获取或设置TCC事务上下文
        /// </summary>
        public static TccTransactionContext? TccContext
        {
            get => TccTransactionContext.Value;
            set => TccTransactionContext.Value = value;
        }
        
        /// <summary>
        /// 获取或设置Saga事务上下文
        /// </summary>
        public static SagaTransactionContext? SagaContext
        {
            get => SagaTransactionContext.Value;
            set => SagaTransactionContext.Value = value;
        }
        
        /// <summary>
        /// 获取或设置XA事务上下文
        /// </summary>
        public static XaTransactionContext? XaContext
        {
            get => XaTransactionContext.Value;
            set => XaTransactionContext.Value = value;
        }
        
        /// <summary>
        /// 绑定全局事务ID
        /// </summary>
        /// <param name="xid">全局事务ID</param>
        public static void Bind(string xid)
        {
            Xid = xid;
        }
        
        /// <summary>
        /// 解绑全局事务ID
        /// </summary>
        public static void Unbind()
        {
            Xid = null;
        }
        
        /// <summary>
        /// 绑定分支事务类型
        /// </summary>
        /// <param name="branchType">分支事务类型</param>
        public static void BindBranchType(string branchType)
        {
            BranchType = branchType;
        }
        
        /// <summary>
        /// 解绑分支事务类型
        /// </summary>
        public static void UnbindBranchType()
        {
            BranchType = null;
        }
        
        /// <summary>
        /// 绑定AT事务上下文
        /// </summary>
        /// <param name="context">AT事务上下文</param>
        public static void Bind(AtTransactionContext context)
        {
            AtContext = context;
        }
        
        /// <summary>
        /// 解绑AT事务上下文
        /// </summary>
        public static void UnbindAtContext()
        {
            AtContext = null;
        }
        
        /// <summary>
        /// 绑定TCC事务上下文
        /// </summary>
        /// <param name="context">TCC事务上下文</param>
        public static void Bind(TccTransactionContext context)
        {
            TccContext = context;
        }
        
        /// <summary>
        /// 解绑TCC事务上下文
        /// </summary>
        public static void UnbindTccContext()
        {
            TccContext = null;
        }
        
        /// <summary>
        /// 绑定Saga事务上下文
        /// </summary>
        /// <param name="context">Saga事务上下文</param>
        public static void Bind(SagaTransactionContext context)
        {
            SagaContext = context;
        }
        
        /// <summary>
        /// 解绑Saga事务上下文
        /// </summary>
        public static void UnbindSagaContext()
        {
            SagaContext = null;
        }
        
        /// <summary>
        /// 绑定XA事务上下文
        /// </summary>
        /// <param name="context">XA事务上下文</param>
        public static void Bind(XaTransactionContext context)
        {
            XaContext = context;
        }
        
        /// <summary>
        /// 解绑XA事务上下文
        /// </summary>
        public static void UnbindXaContext()
        {
            XaContext = null;
        }
        
        /// <summary>
        /// 是否在全局事务中
        /// </summary>
        public static bool InGlobalTransaction => !string.IsNullOrEmpty(Xid);
        
        /// <summary>
        /// 获取默认的分支事务类型
        /// </summary>
        public static string DefaultBranchType => Common.TransactionConstants.BRANCH_TYPE_AT;
        
        /// <summary>
        /// 获取AT事务上下文
        /// </summary>
        /// <returns>AT事务上下文</returns>
        public static AtTransactionContext? GetAtTransactionContext()
        {
            return AtContext;
        }
        
        /// <summary>
        /// 获取TCC事务上下文
        /// </summary>
        /// <returns>TCC事务上下文</returns>
        public static TccTransactionContext? GetTccTransactionContext()
        {
            return TccContext;
        }
        
        /// <summary>
        /// 获取Saga事务上下文
        /// </summary>
        /// <returns>Saga事务上下文</returns>
        public static SagaTransactionContext? GetSagaTransactionContext()
        {
            return SagaContext;
        }
        
        /// <summary>
        /// 获取XA事务上下文
        /// </summary>
        /// <returns>XA事务上下文</returns>
        public static XaTransactionContext? GetXaTransactionContext()
        {
            return XaContext;
        }
        
        /// <summary>
        /// 清理所有上下文
        /// </summary>
        public static void Clear()
        {
            Xid = null;
            BranchType = null;
            AtContext = null;
            TccContext = null;
            SagaContext = null;
            XaContext = null;
        }
    }
}